package com.thread;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class CLHLock implements Lock {

	class QNode {
		public boolean lock = false;
	}

	private AtomicReference<QNode> tail;
	private ThreadLocal<QNode> myQNode;
	private ThreadLocal<QNode> preQNode;

	public CLHLock() {
		this.myQNode = new ThreadLocal<QNode>() {
			protected QNode initialValue() {
				return new QNode();
			}
		};
		this.preQNode = new ThreadLocal<QNode>() {
			protected QNode initialValue() {
				return new QNode();
			}
		};
	}

	@Override
	public void lock() {
		QNode qNode = myQNode.get();
		qNode.lock = true;
		QNode myPreQNode = tail.getAndSet(qNode);
		preQNode.set(myPreQNode);
		while (myPreQNode.lock) {

		}
	}

	@Override
	public void unlock() {
		// TODO Auto-generated method stub
		QNode qNode = myQNode.get();
		qNode.lock = false;
		myQNode.set(preQNode.get());
	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean tryLock() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Condition newCondition() {
		// TODO Auto-generated method stub
		return null;
	}

}